package com.zndroid.layertree.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;

import com.zndroid.layertree.bean.IBean;
import com.zndroid.layertree.vh.ExpandableViewHolder;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public abstract class ABaseExpandableAdapter
        <
            G extends IBean<C>,
            C extends IBean,
            G_VH extends ExpandableViewHolder,
            C_VH extends ExpandableViewHolder
        >
        extends BaseExpandableListAdapter {

    private Context context;
    private List<G> groupData;

    protected abstract @LayoutRes int bindGroupItemViewId();
    protected abstract @LayoutRes int bindChildItemViewId();
    protected abstract @NonNull G_VH bindGroupVH(View itemView, int type, ViewGroup parent);
    protected abstract @NonNull C_VH bindChildVH(View itemView, int type, ViewGroup parent);
    protected abstract void onBindGroupData(G_VH vh, G group, int groupPosition);
    protected abstract void onBindChildData(C_VH vh, C child, int groupPosition, int childPosition);

    public ABaseExpandableAdapter(Context context) {
       this(context, new CopyOnWriteArrayList<>());
    }

    public ABaseExpandableAdapter(Context context, List<G> groupData) {
        this.context = context;
        this.groupData = groupData;
    }

    public void setNewData(List<G> groupData) {
        this.groupData.clear();
        this.groupData = groupData;
        notifyDataSetChanged();
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        G_VH holder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(bindGroupItemViewId(), null);

            holder = bindGroupVH(convertView, getGroupType(groupPosition), parent);
            convertView.setTag(holder);
        } else {
            holder = (G_VH) convertView.getTag();
        }

        onBindGroupData(holder, groupData.get(groupPosition), groupPosition);
        return convertView;
    }


    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        C_VH holder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(bindChildItemViewId(), null);

            holder = bindChildVH(convertView, getChildType(groupPosition, childPosition), parent);
            convertView.setTag(holder);
        } else {
            holder = (C_VH) convertView.getTag();
        }

        onBindChildData(holder, (C) groupData.get(groupPosition).getSubList().get(childPosition), groupPosition, childPosition);
        return convertView;
    }

    @Override
    public G getGroup(int groupPosition) {
        return groupData.get(groupPosition);
    }

    @Override
    public C getChild(int groupPosition, int childPosition) {
        return (C) groupData.get(groupPosition).getSubList().get(childPosition);
    }

    @Override
    public int getGroupCount() {
        return null == groupData ? 0 : groupData.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return (null == groupData || null == groupData.get(groupPosition).getSubList()) ? 0 : groupData.get(groupPosition).getSubList().size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupData.get(groupPosition).getId();
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return groupData.get(groupPosition).getSubList().get(childPosition).getId();
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }
}
